﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenCvSharp;

namespace FinallyVideoCaptureTest
{
    public partial class SettingsForm : Form
    {
        public SettingsForm()
        {
            InitializeComponent();
        }

        private void SettingsForm_Load(object sender, EventArgs e)
        {

        }
        double widthPerc = 0;//比例
        double heightPerc = 0;
        bool trueClick = false;
        Point startPoint = new Point();
        Point endPoint = new Point();
        bool hasMouse = false;
        public Point GetStartPoint { get; private set; }
        public Point GetEndPoint { get; private set; }

        private CvRect rect;
        public CvRect GetMonitorArea { get { return rect; } }
        private string filePath = string.Empty;
        public string FilePath { get { return txtVideoPath.Text.Trim(); } }

        private void btnBrowseVideo_Click(object sender, EventArgs e)
        {
            string fPath = string.Empty;
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                //ofd.InitialDirectory = Application.StartupPath;
                ofd.RestoreDirectory = true;
                ofd.Filter = "AVI 文件|*.avi|Jpg 文件|*.jpg|bmp 文件|*.bmp";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    fPath = ofd.FileName;
                    txtVideoPath.Text = fPath;
                    Image bmap;
                    if (fPath.EndsWith(".avi"))
                    {
                        this.filePath = fPath;
                        bmap = CatchFrame(fPath);
                    }
                    else
                    {
                        bmap = Bitmap.FromFile(fPath);
                    }
                    if (bmap != null) SuofangImage((Bitmap)bmap);
                    else MessageBox.Show("文件没有加载成功！");
                }
            }
        }

        protected void SuofangImage(Bitmap bmap)
        {
            Image img = (Image)bmap;
            widthPerc = img.Width * 1.0 / picDesignPic.Width; //宽的比例
            heightPerc = img.Height * 1.0 / picDesignPic.Height; //长的比例
            Bitmap b = new Bitmap(picDesignPic.Width, picDesignPic.Height);//缩放
            Graphics g = Graphics.FromImage(b);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.DrawImage(img, new Rectangle(0, 0, picDesignPic.Width, picDesignPic.Height), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
            picDesignPic.Image = (Image)b;
            g.Dispose();
            bmap.Dispose();
        }

        public Bitmap CatchFrame(string videoPath)
        {
            CvCapture capture = new CvCapture(videoPath);
            if (capture.FrameCount > 0)
            {
                IplImage picFrame = capture.QueryFrame();
                return picFrame.ToBitmap();
            }
            return null;
        }

        private void btnDrawRectangle_Click(object sender, EventArgs e)
        {
            trueClick = true;
        }

        protected bool chechLiveImg()
        {
            return (picDesignPic.Image != null) ? true : false;
        }

        protected void GetContent()
        {
            SetStartEndPointValue();

            int sx = (int)this.GetStartPoint.X;
            int sy = (int)this.GetStartPoint.Y;
            int ex = (int)this.GetEndPoint.X;
            int ey = (int)this.GetEndPoint.Y;

            txtPoints.Text = string.Format("s: x {0} y {1} e: x {2} y {3}",
                                            sx.ToString(), sy.ToString(), ex.ToString(), ey.ToString());
        }

        private void SetStartEndPointValue()
        {
            if (startPoint.X > endPoint.X && startPoint.Y < endPoint.Y)
            {
                this.GetStartPoint = new Point(Convert.ToInt32(endPoint.X * widthPerc), Convert.ToInt32(startPoint.Y * heightPerc));
                this.GetEndPoint = new Point(Convert.ToInt32(startPoint.X * widthPerc), Convert.ToInt32(endPoint.Y * heightPerc));
            }
            if (startPoint.X < endPoint.X && startPoint.Y > endPoint.Y)
            {
                this.GetStartPoint = new Point(Convert.ToInt32(startPoint.X * widthPerc), Convert.ToInt32(endPoint.Y * heightPerc));
                this.GetEndPoint = new Point(Convert.ToInt32(endPoint.X * widthPerc), Convert.ToInt32(startPoint.Y * heightPerc));
            }
            if (startPoint.X > endPoint.X && startPoint.Y > endPoint.Y)
            {
                this.GetStartPoint = new Point(Convert.ToInt32(endPoint.X * widthPerc), Convert.ToInt32(endPoint.Y * heightPerc));
                this.GetEndPoint = new Point(Convert.ToInt32(startPoint.X * widthPerc), Convert.ToInt32(startPoint.Y * heightPerc));
            }
            if (startPoint.X < endPoint.X && startPoint.Y < endPoint.Y)
            {
                this.GetStartPoint = new Point(Convert.ToInt32(startPoint.X * widthPerc), Convert.ToInt32(startPoint.Y * heightPerc));
                this.GetEndPoint = new Point(Convert.ToInt32(endPoint.X * widthPerc), Convert.ToInt32(endPoint.Y * heightPerc));
            }
        }

        Pen nPen = new Pen(Color.Red, 0.5f);
        private void MyDrawReversibleRectangle(Point p1, Point p2)
        {
            Rectangle rc = new Rectangle();
            p1 = PointToScreen(p1);
            p2 = PointToScreen(p2);

            if (p1.X < p2.X)
            {
                rc.X = p1.X;
                rc.Width = p2.X - p1.X;
            }
            else
            {
                rc.X = p2.X;
                rc.Width = p1.X - p2.X;
            }
            if (p1.Y < p2.Y)
            {
                rc.Y = p1.Y;
                rc.Height = p2.Y - p1.Y;
            }
            else
            {
                rc.Y = p2.Y;
                rc.Height = p1.Y - p2.Y;
            }

            ControlPaint.DrawReversibleFrame(rc,
                           this.BackColor, FrameStyle.Dashed);

        }

        private void picDesignPic_MouseDown(object sender, MouseEventArgs e)
        {
            if (chechLiveImg() && trueClick)
            {
                startPoint.X = e.Location.X;
                startPoint.Y = e.Location.Y;
                endPoint.X = -1;
                endPoint.Y = -1;
                hasMouse = true;
            }
        }

        private void picDesignPic_MouseMove(object sender, MouseEventArgs e)
        {
            Point ptCurrent = new Point(e.Location.X, e.Location.Y);
            if (hasMouse)
            {
                if (((ptCurrent.X <= picDesignPic.Width - 1) && (ptCurrent.X >= 0)) && ((ptCurrent.Y <= picDesignPic.Height - 1) && (ptCurrent.Y >= 0)))
                {
                    if (endPoint.X != -1)
                        MyDrawReversibleRectangle(startPoint, endPoint);
                    endPoint = ptCurrent;
                    MyDrawReversibleRectangle(startPoint, endPoint);
                }
            }
        }

        private void picDesignPic_MouseUp(object sender, MouseEventArgs e)
        {
            if (chechLiveImg() && trueClick)
            {
                endPoint.X = e.Location.X;
                endPoint.Y = e.Location.Y;

                if (startPoint.X < 0) startPoint.X = 0;
                if (startPoint.Y < 0) startPoint.Y = 0;
                if (endPoint.X > picDesignPic.Width) endPoint.X = picDesignPic.Width;
                if (endPoint.Y > picDesignPic.Height) endPoint.Y = picDesignPic.Height;

                GetContent();

                hasMouse = false;

                endPoint.X = 0;
                endPoint.Y = 0;
                startPoint.X = -1;
                startPoint.Y = -1;
            }
        }

        private void btnInvalidate_Click(object sender, EventArgs e)
        {
            this.picDesignPic.Invalidate();
            this.txtPoints.Text = string.Empty;
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            int sx = (int)this.GetStartPoint.X;
            int sy = (int)this.GetStartPoint.Y;
            int ex = (int)this.GetEndPoint.X;
            int ey = (int)this.GetEndPoint.Y;
            rect = new CvRect(sx, sy, Math.Abs(ex - sx), Math.Abs(ey - sy));
            this.DialogResult = DialogResult.OK;
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        public bool GetUpdateState { get;private set; }
        private void chUsedCheck_Click(object sender, EventArgs e)
        {
            chUsedCheck.Checked = chUsedCheck.Checked ? true : false;
            this.GetUpdateState = chUsedCheck.Checked;
        }
    }
}
